1 /****************************** Module Header ******************************\
3 Project: CppShellExtCopyHookHandler
4 Copyright (c) Microsoft Corporation.
6 The file implements the reusable helper functions to register and unregister
7 in-process COM components and shell copy hook handlers in the registry.
9 RegisterInprocServer - register the in-process component in the registry.
10 UnregisterInprocServer - unregister the in-process component in the registry.
11 RegisterShellExtFolderCopyHookHandler - register the folder copy hook handler.
12 UnregisterShellExtFolderCopyHookHandler - unregister the copy hook handler.
14 This source is subject to the Microsoft Public License.
15 See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
16 All other rights reserved.
18 THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
19 EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
20 WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
21 \***************************************************************************/
27 #pragma region Registry Helper Functions
30 // FUNCTION: SetHKCRRegistryKeyAndValue
32 // PURPOSE: The function creates a HKCR registry key and sets the specified
36 // * pszSubKey - specifies the registry key under HKCR. If the key does not
37 // exist, the function will create the registry key.
38 // * pszValueName - specifies the registry value to be set. If pszValueName
39 // is NULL, the function will set the default value.
40 // * pszData - specifies the string data of the registry value.
43 // If the function succeeds, it returns S_OK. Otherwise, it returns an
44 // HRESULT error code.
46 HRESULT
SetHKCRRegistryKeyAndValue(PCWSTR pszSubKey
, PCWSTR pszValueName
,
52 // Creates the specified registry key. If the key already exists, the
54 hr
= HRESULT_FROM_WIN32(RegCreateKeyEx(HKEY_CLASSES_ROOT
, pszSubKey
, 0,
55 NULL
, REG_OPTION_NON_VOLATILE
, KEY_WRITE
, NULL
, &hKey
, NULL
));
61 // Set the specified value of the key.
62 DWORD cbData
= lstrlen(pszData
) * sizeof(*pszData
);
63 hr
= HRESULT_FROM_WIN32(RegSetValueEx(hKey
, pszValueName
, 0,
64 REG_SZ
, reinterpret_cast<const BYTE
*>(pszData
), cbData
));
77 // FUNCTION: RegisterInprocServer
79 // PURPOSE: Register the in-process component in the registry.
82 // * pszModule - Path of the module that contains the component
83 // * clsid - Class ID of the component
84 // * pszFriendlyName - Friendly name
85 // * pszThreadModel - Threading model
87 // NOTE: The function creates the HKCR\CLSID\{<CLSID>} key in the registry.
93 // ForceRemove {<CLSID>} = s '<Friendly Name>'
95 // InprocServer32 = s '%MODULE%'
97 // val ThreadingModel = s '<Thread Model>'
103 HRESULT
RegisterInprocServer(PCWSTR pszModule
, const CLSID
& clsid
,
104 PCWSTR pszFriendlyName
, PCWSTR pszThreadModel
)
106 if (pszModule
== NULL
|| pszThreadModel
== NULL
)
113 wchar_t szCLSID
[MAX_PATH
];
114 StringFromGUID2(clsid
, szCLSID
, ARRAYSIZE(szCLSID
));
116 wchar_t szSubkey
[MAX_PATH
];
118 // Create the HKCR\CLSID\{<CLSID>} key.
119 hr
= StringCchPrintf(szSubkey
, ARRAYSIZE(szSubkey
), L
"CLSID\\%s", szCLSID
);
122 hr
= SetHKCRRegistryKeyAndValue(szSubkey
, NULL
, pszFriendlyName
);
124 // Create the HKCR\CLSID\{<CLSID>}\InprocServer32 key.
127 hr
= StringCchPrintf(szSubkey
, ARRAYSIZE(szSubkey
),
128 L
"CLSID\\%s\\InprocServer32", szCLSID
);
131 // Set the default value of the InprocServer32 key to the
132 // path of the COM module.
133 hr
= SetHKCRRegistryKeyAndValue(szSubkey
, NULL
, pszModule
);
136 // Set the threading model of the component.
137 hr
= SetHKCRRegistryKeyAndValue(szSubkey
,
138 L
"ThreadingModel", pszThreadModel
);
149 // FUNCTION: UnregisterInprocServer
151 // PURPOSE: Unegister the in-process component in the registry.
154 // * clsid - Class ID of the component
156 // NOTE: The function deletes the HKCR\CLSID\{<CLSID>} key in the registry.
158 HRESULT
UnregisterInprocServer(const CLSID
& clsid
)
162 wchar_t szCLSID
[MAX_PATH
];
163 StringFromGUID2(clsid
, szCLSID
, ARRAYSIZE(szCLSID
));
165 wchar_t szSubkey
[MAX_PATH
];
167 // Delete the HKCR\CLSID\{<CLSID>} key.
168 hr
= StringCchPrintf(szSubkey
, ARRAYSIZE(szSubkey
), L
"CLSID\\%s", szCLSID
);
171 hr
= HRESULT_FROM_WIN32(RegDeleteTree(HKEY_CLASSES_ROOT
, szSubkey
));
179 // FUNCTION: RegisterShellExtFolderCopyHookHandler
181 // PURPOSE: Register the folder copy hook handler.
184 // * pszName - The name of the copy hook handler
185 // * clsid - Class ID of the component
187 // NOTE: The function creates the following key in the registry.
191 // NoRemove Directory
195 // NoRemove CopyHookHandlers
197 // <Name> = s '{<CLSID>}'
203 HRESULT
RegisterShellExtFolderCopyHookHandler(PCWSTR pszName
, const CLSID
& clsid
)
205 if (pszName
== NULL
|| wcslen(pszName
) == 0)
210 wchar_t szCLSID
[MAX_PATH
];
211 StringFromGUID2(clsid
, szCLSID
, ARRAYSIZE(szCLSID
));
213 wchar_t szSubkey
[MAX_PATH
];
215 // Folder copy hook handlers are typically registered under the following
216 // subkey: HKCR\Directory\shellex\CopyHookHandlers.
217 // Create the key HKCR\Directory\shellex\CopyHookHandlers\<Name>
218 HRESULT hr
= StringCchPrintf(szSubkey
, ARRAYSIZE(szSubkey
),
219 L
"Directory\\shellex\\CopyHookHandlers\\%s", pszName
);
222 // Set the default value of the key.
223 hr
= SetHKCRRegistryKeyAndValue(szSubkey
, NULL
, szCLSID
);
231 // FUNCTION: UnregisterShellExtFolderCopyHookHandler
233 // PURPOSE: Unregister the folder copy hook handler.
236 // * pszName - The name of the copy hook handler
238 // NOTE: The function removes the <Name> key under
239 // HKCR\Directory\shellex\CopyHookHandlers in the registry.
241 HRESULT
UnregisterShellExtFolderCopyHookHandler(PCWSTR pszName
)
243 if (pszName
== NULL
|| wcslen(pszName
) == 0)
248 wchar_t szSubkey
[MAX_PATH
];
250 // Remove the HKCR\Directory\shellex\CopyHookHandlers\<Name> key.
251 HRESULT hr
= StringCchPrintf(szSubkey
, ARRAYSIZE(szSubkey
),
252 L
"Directory\\shellex\\CopyHookHandlers\\%s", pszName
);
255 hr
= HRESULT_FROM_WIN32(RegDeleteTree(HKEY_CLASSES_ROOT
, szSubkey
));